﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChromaCode.Models;

namespace ChromaCode.Extensions
{
    /// <summary>
    /// Extensions to make working with rules easier
    /// </summary>
    internal static class RuleExtensions
    {
        /// <summary>
        /// Search through a list of word rules to see if any contain the specified word
        /// </summary>
        /// <param name="rules">The list of rules to search</param>
        /// <param name="word">The word to search for in the list of word rules</param>
        /// <returns>A matching word rule</returns>
        public static WordRule FindWordRule(this List<WordRule> rules, string word)
        {
            WordRule result = null;

            // Search that list for any that contain the supplied word
            if ((rules != null) && (rules.Count > 0))
            {
                // the following search will search through the list of words in the rule and ignore case
                result = rules.FirstOrDefault(x => x.Words.FindIndex(y => y.Equals(word, StringComparison.OrdinalIgnoreCase)) != -1);
            }

            return result;
        }

        /// <summary>
        /// Search through a list of character rules to see if any contain the specified char
        /// </summary>
        /// <param name="rules">The list of rules to search</param>
        /// <param name="character">The char to search for in the list of char rules</param>
        /// <returns>A matching character rule</returns>
        public static CharacterRule FindCharacterRule(this List<CharacterRule> rules, char character)
        {
            CharacterRule result = null;

            // Search that list for any that contain the supplied character
            if ((rules != null) && (rules.Count > 0))
            {
                result = rules.Where(x => x.Characters.Contains(character)).FirstOrDefault();
            }

            return result;
        }

        /// <summary>
        /// Search through a list of rules to see if any are groups rules and, if they are if any contain match the
        /// supplied start and end group strings
        /// </summary>
        /// <param name="rules">The list of rules to search</param>
        /// <param name="groupStart">The string that representsa the start of the group</param>
        /// <param name="groupEnd">The string that represents the end of the group</param>
        /// <returns>A matching group rule rule</returns>
        /// <remarks>If groupEnd is string.Empty then this is a sigle line group rule</remarks>
        public static GroupRule FindGroupRule(this List<Rule> rules, string groupStart, string groupEnd)
        {
            GroupRule result = null;

            // Get a list of rules that are of the type GroupRule
            List<GroupRule> groupRules = rules.Where(x => x.TypeOfRule == RuleType.GroupHighlighter).Select(y => (GroupRule)y).ToList();

            // Search the list for any that contain the supplied start and end strings for the group
            if ((groupRules != null) && (groupRules.Count > 0))
            {
                result = groupRules.Where(x => (x.StartString.Equals(groupStart, StringComparison.OrdinalIgnoreCase))
                    && (x.EndString.Equals(groupEnd, StringComparison.OrdinalIgnoreCase))).FirstOrDefault();
            }

            return result;
        }

        /// <summary>
        /// Search through a list of rules to see if any are groups rules which start with the supplied groupStart string
        /// </summary>
        /// <param name="rules">The list of rules to search</param>
        /// <param name="groupStart">The string that representsa the start of the group</param>
        /// <returns>A matching group rule rule</returns>        
        public static GroupRule FindSingleLineGroupRule(this List<Rule> rules, string groupStart)
        {
            return FindGroupRule(rules, groupStart, string.Empty);
        }
    }
}
